import { RandUtil } from "../../util/RandUtil";
import BaseAI, { IBaseAI } from "./BaseAI";
import SnakeNode from "../SnakeNode";

const ru = RandUtil

export interface IAIAwaySnake extends IBaseAI {
    checkDis: number | [number, number]
    /** 躲避时偏移角度 默认:0 */
    offsetAng?: number | [number, number]
}

export default class AIAwaySnake extends BaseAI {

    private _checkDisArr: number[]
    private _offsetAngArr: number[]
    private _checkDis: number
    private _offsetAng: number = 0
    private _lastAwayNode: SnakeNode

    constructor(obj: IAIAwaySnake) {
        super(obj)
        this._checkDisArr = this.toMinMax(obj.checkDis)
        this._offsetAngArr = this.toMinMax(obj.offsetAng || 0)
    }

    getKey(): string { return "ai_away_snake" }

    aiStart() {
        let head = this.head
        this._checkDis = ru.rand2(this._checkDisArr) * head.w + head.w
        let checkCol = head.cp().setW(this._checkDis)
        let chunks = this.world.getChunks(checkCol)
        let nodes = this.world.getSnakeNodesExclude(chunks, [this.snake])

        if (!nodes.some(node => checkCol.collide(node))) {
            this.recheck()
        }
    }

    ai(dt: number): void {

        let head = this.head
        let awayNode: SnakeNode
        let minDis: number = Number.MAX_SAFE_INTEGER
        let checkCol = head.cp().setW(this._checkDis)
        let chunks = this.world.getChunks(checkCol)
        let nodes = this.world.getSnakeNodesExclude(chunks, [this.snake])

        nodes.forEach(node => {
            //找到检测范围内的最近的蛇节点
            if (checkCol.collide(node)) {
                let dis = checkCol.dis(node)
                if (dis < minDis) {
                    minDis = dis
                    awayNode = node
                }
            }
        })

        if (awayNode) {
            this.aiVal.nearestNode = awayNode
            if (awayNode != this._lastAwayNode) {
                this._offsetAng = (ru.chance(0.5) ? 1 : -1) * ru.rand2(this._offsetAngArr)
                this._lastAwayNode = awayNode
            }
            head.toAng = awayNode.angTo(head) + this._offsetAng
        } else {
            this.recheck()
        }
    }

    aiStop() {
        this.aiVal.nearestNode = null
        this._lastAwayNode = null
    }

}